/**
 * 添加拦截器：
 *   - 拦截 request 请求
 *   - 拦截 uploadFile 文件上传
 */

import type { IResponse } from '@/types'

// 请求的 baseURL
const baseURL = 'https://www.v2tn.com/api'

// 添加拦截器
const httpInterceptor: UniApp.InterceptorOptions = {
  // 请求前拦截
  invoke(options: UniApp.RequestOptions) {
    /* 1. 非 http 开头需拼接地址 */
    if (!options.url.startsWith('http')) {
      options.url = baseURL + options.url
    }
    /* 2. 设置请求超时时间 */
    if (!options.timeout) {
      options.timeout = 15 * 1000 // 默认值为 60s
    }
    /* 3. 根据不同平台添加特定的请求头标识 */
    // #ifdef MP-WEIXIN
    options.header = { 'source-client': 'miniapp', ...options.header }
    // #endif
    // #ifdef APP
    options.header = { 'source-client': 'miniapp', ...options.header }
    // #endif
    /* 4. 添加 token 请求头标识 */
    // 添加 token 请求头标识
    // options.header.Authorization = token
  },
}

uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)

/**
 * 请求函数
 * @param UniApp.RequestOptions
 * @returns Promise
 *   1. 返回 Promise 对象
 *   2. 请求成功
 *     2.1 提取核心数据 res.data
 *     2.2 添加类型, 支持泛型
 *   3. 请求失败
 *     3.1 401错误 -> 清理用户信息, 跳转到登录页
 *     3.2 其它错误 -> 根据后端错误信息轻提示
 *     3.3 网络错误 -> 提示用户换网络
 */
// 2.2 添加类型, 支持泛型
const request = <T>(options: UniApp.RequestOptions) => {
  // 1. 返回 Promise 对象
  return new Promise<IResponse<T>>((resolve, reject) => {
    uni.request({
      ...options,
      // 成功回调
      success(res) {
        // 状态码为 2xx 时, 表示获取数据成功
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 2.1 提取核心数据 res.data
          resolve(res.data as IResponse<T>)
        } else if (res.statusCode === 401) {
          // 3.1 401错误 -> 清理用户信息, 跳转到登录页
          // TODO 清理用户信息, 跳转到登录页
          reject(res)
        } else {
          // 3.2 其它错误 -> 根据后端错误信息轻提示
          uni.showToast({ icon: 'none', title: (res.data as IResponse<T>)?.message || '请求错误' })
          reject(res)
        }
      },
      // 响应失败
      fail(error) {
        // 3.3 网络错误 -> 提示用户换网络
        uni.showToast({ icon: 'none', title: '网络错误, 请切换网络' })
        reject(error)
      },
    })
  })
}

export { request }
